import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import torchimports
numpy, torch (선택학습)
numpy, torch는 엄청 비슷해요
- torch.tensor() = np.array() 처럼 생각해도 무방
np.array([1,2,3]), torch.tensor([1,2,3])(array([1, 2, 3]), tensor([1, 2, 3]))
- 소수점의 정밀도에서 차이가 있음 (torch가 좀 더 쪼잔함)
np.array([3.123456789])array([3.12345679])
torch.tensor([3.123456789]) #GPU메모리에 저장해서 tensor([3.1235])
- 기본적인 numpy 문법은 np 대신에 torch를 써도 무방 // 완전 같지는 않음
np.arange(10), torch.arange(10)(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
np.linspace(0,1,10), torch.linspace(0,1,10)(array([0. , 0.11111111, 0.22222222, 0.33333333, 0.44444444,
0.55555556, 0.66666667, 0.77777778, 0.88888889, 1. ]),
tensor([0.0000, 0.1111, 0.2222, 0.3333, 0.4444, 0.5556, 0.6667, 0.7778, 0.8889,
1.0000]))
np.random.randn(10)array([ 0.68732684, -0.53367188, 0.27916096, 0.28236708, 0.03800702,
-0.66236923, 1.32472364, -0.11671166, -0.77019834, -1.14755872])
torch.randn(10)tensor([ 0.8525, 0.2257, 0.3406, -0.4713, 1.5393, -2.0060, -0.4257, 3.0482,
-0.7659, 0.3265])
length \(n\) vector, \(n \times 1\) col-vector, \(1 \times n\) row-vector
- 길이가 3인 벡터 선언방법
a = torch.tensor([1,2,3])
a.shapetorch.Size([3])
- 3x1 col-vec 선언방법
(방법1)
a = torch.tensor([[1],[2],[3]])
a.shapetorch.Size([3, 1])
(방법2)
a = torch.tensor([1,2,3]).reshape(3,1)
a.shapetorch.Size([3, 1])
- 1x3 row-vec 선언방법
(방법1)
a = torch.tensor([[1,2,3]])
a.shapetorch.Size([1, 3])
(방법2)
a = torch.tensor([1,2,3]).reshape(1,3)
a.shapetorch.Size([1, 3])
- 3x1 col-vec 선언방법, 1x3 row-vec 선언방법에서 [[1],[2],[3]] 혹은 [[1,2,3]] 와 같은 표현이 이해안되면 아래링크로 가셔서
https://guebin.github.io/STBDA2022/2022/03/14/(2주차)-3월14일.html
첫번째 동영상 12:15 - 22:45 에 해당하는 분량을 학습하시길 바랍니다.
torch의 dtype
- 기본적으로 torch는 소수점으로 저장되면 dtype=torch.float32 가 된다. (이걸로 맞추는게 편리함)
tsr = torch.tensor([1.23,2.34])
tsrtensor([1.2300, 2.3400])
tsr.dtypetorch.float32
#float64보다 데이터를 적게 쓴다는 뜻-> float32- 정수로 선언하더라도 dtype를 torch.float32로 바꾸는게 유리함
(안 좋은 선언예시)
tsr = torch.tensor([1,2])
tsr tensor([1, 2])
tsr.dtypetorch.int64
(좋은 선언예시1)
tsr = torch.tensor([1,2],dtype=torch.float32)
tsr tensor([1., 2.])
tsr.dtypetorch.float32
(좋은 선언예시2)
tsr = torch.tensor([1,2.0])
tsr tensor([1., 2.])
tsr.dtypetorch.float32
(사실 int로 선언해도 나중에 float으로 바꾸면 큰 문제없음)
tsr = torch.tensor([1,2]).float()
tsrtensor([1., 2.])
tsr.dtypetorch.float32
- 왜 정수만으로 torch.tensor를 만들때에도 torch.float32로 바꾸는게 유리할까? \(\to\) torch.tensor끼리의 연산에서 문제가 될 수 있음
별 문제 없을수도 있지만
torch.tensor([1,2])-torch.tensor([1.0,2.0]) tensor([0., 0.])
아래와 같이 에러가 날수도 있다
(에러1)
torch.tensor([[1.0,0.0],[0.0,1.0]]) @ torch.tensor([[1],[2]]) RuntimeError: expected scalar type Float but found Long
(에러2)
torch.tensor([[1,0],[0,1]]) @ torch.tensor([[1.0],[2.0]])RuntimeError: expected scalar type Long but found Float
(해결1) 둘다 정수로 통일
torch.tensor([[1,0],[0,1]]) @ torch.tensor([[1],[2]])tensor([[1],
[2]])
(해결2) 둘다 소수로 통일 <– 더 좋은 방법임
torch.tensor([[1.0,0.0],[0.0,1.0]]) @ torch.tensor([[1.0],[2.0]])tensor([[1.],
[2.]])
shape of vector
- 행렬곱셈에 대한 shape 조심
A = torch.tensor([[2.00,0.00],[0.00,3.00]])
b1 = torch.tensor([[-1.0,-5.0]])
b2 = torch.tensor([[-1.0],[-5.0]])
b3 = torch.tensor([-1.0,-5.0])A.shape,b1.shape,b2.shape,b3.shape(torch.Size([2, 2]), torch.Size([1, 2]), torch.Size([2, 1]), torch.Size([2]))
- A@b1: 계산불가, b1@A: 계산가능
A@b1 #행렬계산이라고 생각RuntimeError: mat1 and mat2 shapes cannot be multiplied (2x2 and 1x2)
b1@Atensor([[ -2., -15.]])
- A@b2: 계산가능, b2@A: 계산불가
A@b2tensor([[ -2.],
[-15.]])
b2@ARuntimeError: mat1 and mat2 shapes cannot be multiplied (2x1 and 2x2)
- A@b3: 계산가능, b3@A: 계산가능
(A@b3).shape ## b3를 마치 col-vec 처럼 해석torch.Size([2])
(b3@A).shape ## b3를 마지 row-vec 처럼 해석torch.Size([2])
- 브로드캐스팅
a = torch.tensor([1,2,3]) #a는 길이가 3인 벡터지만... 연산이 된다.
a - 1tensor([0, 1, 2])
b = torch.tensor([[1],[2],[3]]) #b는 컬럼 벡터
b - 1tensor([[0],
[1],
[2]])
a - b # a를 row-vec 로 해석
#불필요한 오류를 막기 위해서 dimension잘 써놓기tensor([[ 0, 1, 2],
[-1, 0, 1],
[-2, -1, 0]])
Review: step1~4
df = pd.read_csv("https://raw.githubusercontent.com/guebin/DL2022/master/_notebooks/2022-09-22-regression.csv")
df| x | y | |
|---|---|---|
| 0 | -2.482113 | -8.542024 |
| 1 | -2.362146 | -6.576713 |
| 2 | -1.997295 | -5.949576 |
| 3 | -1.623936 | -4.479364 |
| 4 | -1.479192 | -4.251570 |
| ... | ... | ... |
| 95 | 2.244400 | 10.325987 |
| 96 | 2.393501 | 12.266493 |
| 97 | 2.605604 | 13.098280 |
| 98 | 2.605658 | 12.546793 |
| 99 | 2.663240 | 13.834002 |
100 rows × 2 columns
torch.tensor(df.x)
#dtype=float32로 지정하면 밑에 dtype=torch.float64가 안붙는다. 메모리를 아끼기위해서 데이터타입을 float32로바꾼다리tensor([-2.4821, -2.3621, -1.9973, -1.6239, -1.4792, -1.4635, -1.4509, -1.4435,
-1.3722, -1.3079, -1.1904, -1.1092, -1.1054, -1.0875, -0.9469, -0.9319,
-0.8643, -0.7858, -0.7549, -0.7421, -0.6948, -0.6103, -0.5830, -0.5621,
-0.5506, -0.5058, -0.4806, -0.4738, -0.4710, -0.4676, -0.3874, -0.3719,
-0.3688, -0.3159, -0.2775, -0.2772, -0.2734, -0.2721, -0.2668, -0.2155,
-0.2000, -0.1816, -0.1708, -0.1565, -0.1448, -0.1361, -0.1057, -0.0603,
-0.0559, -0.0214, 0.0655, 0.0684, 0.1195, 0.1420, 0.1521, 0.1568,
0.2646, 0.2656, 0.3157, 0.3220, 0.3461, 0.3984, 0.4190, 0.5443,
0.5579, 0.5913, 0.6148, 0.6469, 0.6469, 0.6523, 0.6674, 0.7059,
0.7141, 0.7822, 0.8154, 0.8668, 0.9291, 0.9804, 0.9853, 0.9941,
1.0376, 1.0393, 1.0697, 1.1024, 1.1126, 1.1532, 1.2289, 1.3403,
1.3494, 1.4279, 1.4994, 1.5031, 1.5437, 1.6789, 2.0832, 2.2444,
2.3935, 2.6056, 2.6057, 2.6632], dtype=torch.float64)
x= torch.tensor(df.x,dtype=torch.float32).reshape(100,1)
y= torch.tensor(df.y,dtype=torch.float32).reshape(100,1)
# _1 = torch.ones([100,1])
# X = torch.concat([_1,x]),axis=1
X= torch.tensor([[1]*100,x]).T #torch.ones([100,1])로 써도 됨
What = torch.tensor([[-5.0],[10.0]],requires_grad=True) # 아무 점이나 주어보자! (-5,10)
Whattensor([[-5.],
[10.]], requires_grad=True)
plt.plot(x,y,'o')
#plt.plot(x,-5+10*x,'--')
plt.plot(x,X@What.data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-47-output-1.png)
ver1: loss = sum of squares error
alpha = 1/1000 #학습하는과정에 대한 분류 4가지
What = torch.tensor([[-5.0],[10.0]],requires_grad=True)
for epoc in range(30):
# step1: yhat
yhat = X@What
# step2: loss
loss = torch.sum((y-yhat)**2)
# step3: 미분
loss.backward()
# step4: update
# What.data = What.data - 1/000 * What.grad # alpha = 1/000
# What.grad = None # # gradient청소...
What.data = What.data - alpha * What.grad
What.grad = None # Whattensor([[2.4290],
[4.0144]], requires_grad=True)
plt.plot(x,y,'o')
plt.plot(x,X@What.data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-50-output-1.png)
- note: 왜 What = What - alpha*What.grad 는 안되는지?
ver2: loss = mean squared error = MSE
alpha = 1/10
What = torch.tensor([[-5.0],[10.0]],requires_grad=True)
for epoc in range(30):
# step1: yhat
yhat = X@What
# step2: loss
loss = torch.mean((y-yhat)**2) # 위랑 다른거 여기 mean!!!!
# step3: 미분
loss.backward()
# step4: update
What.data = What.data - alpha * What.grad
What.grad = None #
# mean으로 하면 좋은거: 100개읟 ㅔ이터 1/1000 학습률
# sample size가 달라질때마다 학습률 설정이 힘든데, mean으로 하면 데이터set이 계속 할수잇어서!!Whattensor([[2.4290],
[4.0144]], requires_grad=True)
step1의 다른버전 – net 설계만
ver1: net = torch.nn.Linear(1,1,bias=True)
torch.manual_seed(43052)
net = torch.nn.Linear(in_features=1, out_features=1, bias=True) # 함수를 만들어준다. x가들어가면 y가 나오는 것 가틍ㄴ..
# x.shape 했을때 torch.size(100,1) 이 나온다. 100은 observation이고 뒤쪽에 있는 1이 in_features!!
# out_features는 y.shape의 뒤쪽,,
# net.bias, net.weight 하면 tensor 0.2366 -> w0역할... tensor -0.8791 -> w1역할
# 위 숫자는 최초의 숫자라 아무거나 찍은거 실행할때마다 달라질수 있음.
# 맨 위에 seed를 주면 나중에 교수님 강의할때 편하게` 하려고 plt.plot(x,y,'o')
plt.plot(x,net(x).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-54-output-1.png)
- net에서 \(\hat{w}_0, \hat{w}_1\) 의 값은?
net.weight # w1 Parameter containing:
tensor([[-0.3467]], requires_grad=True)
net.bias # w0 Parameter containing:
tensor([-0.8470], requires_grad=True)
_yhat = -0.8470 + -0.3467*x plt.plot(x,y,'o')
plt.plot(x, _yhat,'--')
plt.plot(x,net(x).data,'-.')_9월 28일__ipynb의_사본_files/figure-html/cell-58-output-1.png)
- 수식표현: \(\hat{y}_i = \hat{w}_0 + \hat{w}_1 x_i = \hat{b} + \hat{w}x_i = -0.8470 + -0.3467 x_i\) for all \(i=1,2,\dots,100\).
ver2: net = torch.nn.Linear(2,1,bias=False)
- 입력이 x가 아닌 X를 넣고 싶다면? (보통 잘 안하긴 해요, 왜? bias=False로 주는게 귀찮거든요) - X는 바이어스가 고려된 상황
net(X) ## 그대로 쓰면 당연히 에러RuntimeError: mat1 and mat2 shapes cannot be multiplied (100x2 and 1x1)
torch.manual_seed(43052)
net = torch.nn.Linear(in_features=2, out_features=1, bias=False) #bias=false:뒤쪽에 더해지는 값인거 같으니까....
# out_features=3으로 쓰면 shape이 [100,3] 된다,,,,,,,,,,, 1이 되야해,,net.weightParameter containing:
tensor([[-0.2451, -0.5989]], requires_grad=True)
net.bias # false로 설정해서 아무것도 안뜸plt.plot(x,y,'o')
plt.plot(x,net(X).data, '--')
plt.plot(x,X@torch.tensor([[-0.2451],[-0.5989]]), '-.')_9월 28일__ipynb의_사본_files/figure-html/cell-63-output-1.png)
- 수식표현: \(\hat{\bf y} = {\bf X} {\bf \hat W} = \begin{bmatrix} 1 & x_1 \\ 1 & x_2 \\ \dots & \dots \\ 1 & x_{100} \end{bmatrix} \begin{bmatrix} -0.2451 \\ -0.5989 \end{bmatrix}\)
잘못된사용1
_x = x.reshape(-1)_xtensor([-2.4821, -2.3621, -1.9973, -1.6239, -1.4792, -1.4635, -1.4509, -1.4435,
-1.3722, -1.3079, -1.1904, -1.1092, -1.1054, -1.0875, -0.9469, -0.9319,
-0.8643, -0.7858, -0.7549, -0.7421, -0.6948, -0.6103, -0.5830, -0.5621,
-0.5506, -0.5058, -0.4806, -0.4738, -0.4710, -0.4676, -0.3874, -0.3719,
-0.3688, -0.3159, -0.2775, -0.2772, -0.2734, -0.2721, -0.2668, -0.2155,
-0.2000, -0.1816, -0.1708, -0.1565, -0.1448, -0.1361, -0.1057, -0.0603,
-0.0559, -0.0214, 0.0655, 0.0684, 0.1195, 0.1420, 0.1521, 0.1568,
0.2646, 0.2656, 0.3157, 0.3220, 0.3461, 0.3984, 0.4190, 0.5443,
0.5579, 0.5913, 0.6148, 0.6469, 0.6469, 0.6523, 0.6674, 0.7059,
0.7141, 0.7822, 0.8154, 0.8668, 0.9291, 0.9804, 0.9853, 0.9941,
1.0376, 1.0393, 1.0697, 1.1024, 1.1126, 1.1532, 1.2289, 1.3403,
1.3494, 1.4279, 1.4994, 1.5031, 1.5437, 1.6789, 2.0832, 2.2444,
2.3935, 2.6056, 2.6057, 2.6632])
torch.manual_seed(43052)
net = torch.nn.Linear(in_features=1,out_features=1) net(_x) #이렇게 하면 에러메시지뜬다리
# net(_x.reshape(100,1))로 바궈줘야 한다.RuntimeError: size mismatch, got 1, 1x1,100
잘못된사용2
torch.manual_seed(43052)
net = torch.nn.Linear(in_features=2,out_features=1) # bias=False를 깜빡.. bias=true로 설정됨 기본으로 net.weightParameter containing:
tensor([[-0.2451, -0.5989]], requires_grad=True)
net.biasParameter containing:
tensor([0.2549], requires_grad=True)
plt.plot(x,y,'o')
plt.plot(x,net(X).data,'--')
plt.plot(x,X@torch.tensor([[-0.2451],[-0.5989]])+0.2549,'-.')
# b hat = 0.2549 의도와는 다르게 모델링 된것..
# plt.plot(x,X@torch.tensor([[-0.2451],[-0.5989]]),'-.')
# bias=f일때_9월 28일__ipynb의_사본_files/figure-html/cell-71-output-1.png)
- 수식표현: \(\hat{\bf y} = {\bf X} {\bf \hat W} + \hat{b}= \begin{bmatrix} 1 & x_1 \\ 1 & x_2 \\ \dots & \dots \\ 1 & x_{100} \end{bmatrix} \begin{bmatrix} -0.2451 \\ -0.5989 \end{bmatrix} + 0.2549\)
step1의 다른버전 – 끝까지
ver1: net = torch.nn.Linear(1,1,bias=True)
- 준비
net = torch.nn.Linear(1,1,bias=True) # in_features=1 에서 1만 써도 뎀, bias 생략해도 뎀
net.weight.data = torch.tensor([[10.0]])
net.bias.data = torch.tensor([-5.0])
net.weight,net.bias(Parameter containing:
tensor([[10.]], requires_grad=True),
Parameter containing:
tensor([-5.], requires_grad=True))
- step1
yhat = net(x) # -5 + 10x 가 첫 값으로 나올것,,,plt.plot(x,y,'o')
plt.plot(x,net(x).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-74-output-1.png)
- step2
loss = torch.mean((y-yhat)**2)- step3
(미분전)
net.bias,net.weight(Parameter containing:
tensor([-5.], requires_grad=True),
Parameter containing:
tensor([[10.]], requires_grad=True))
net.bias.grad, net.weight.grad #grad값이 없는데.... (None, None)
(미분)
loss.backward()(미분후)
net.bias,net.weight(Parameter containing:
tensor([-5.], requires_grad=True),
Parameter containing:
tensor([[10.]], requires_grad=True))
net.bias.grad,net.weight.grad # 미분후에 값 자체는 변화가 없지만 grad값이 (tensor([-13.4225]), tensor([[11.8893]]))
- step4
(업데이트전)
net.bias,net.weight(Parameter containing:
tensor([-5.], requires_grad=True),
Parameter containing:
tensor([[10.]], requires_grad=True))
net.bias.grad, net.weight.grad(tensor([-13.4225]), tensor([[11.8893]]))
(업데이트)
net.bias.data = net.bias.data - 0.1*net.bias.grad # 기울기 0.1
net.weight.data = net.weight.data - 0.1*net.weight.grad net.bias.grad = None # 바뀌기만 하고 청소가 안된상태ㅣ니까 none값으로 지정해주기...
net.weight.grad = None (업데이트후)
net.bias,net.weight(Parameter containing:
tensor([-3.6577], requires_grad=True),
Parameter containing:
tensor([[8.8111]], requires_grad=True))
net.bias.grad, net.weight.grad(None, None)
- 반복
for epoc in range(30):
# step1
yhat = net(x)
# step2
loss = torch.mean((y-yhat)**2)
# step3
loss.backward()
# step4
net.weight.data = net.weight.data - 0.1*net.weight.grad
net.bias.data = net.bias.data - 0.1*net.bias.grad
net.weight.grad = None
net.bias.grad = Noneplt.plot(x,y,'o')
plt.plot(x,net(x).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-88-output-1.png)
ver2: net = torch.nn.Linear(2,1,bias=False)
- 준비
net = torch.nn.Linear(2,1,bias=False)
net.weight.data = torch.tensor([[-5.0, 10.0]])- step1
yhat = net(X)- step2
loss = torch.mean((y-yhat)**2)- step3
(미분전)
net.weightParameter containing:
tensor([[-5., 10.]], requires_grad=True)
net.weight.grad(미분)
loss.backward()(미분후)
net.weightParameter containing:
tensor([[-5., 10.]], requires_grad=True)
net.weight.gradtensor([[-13.4225, 11.8893]])
- step4
(업데이트전)
net.weightParameter containing:
tensor([[-5., 10.]], requires_grad=True)
net.weight.gradtensor([[-13.4225, 11.8893]])
(업데이트)
net.weight.data = net.weight.data - 0.1*net.weight.gradnet.weight.grad = None(업데이트후)
net.weightParameter containing:
tensor([[-3.6577, 8.8111]], requires_grad=True)
net.weight.grad- 반복
net = torch.nn.Linear(2,1,bias=False)
net.weight.data = torch.tensor([[-5.0, 10.0]])plt.plot(x,y,'o')
plt.plot(x,net(X).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-104-output-1.png)
for epoc in range(30):
# step1
yhat = net(X)
# step2
loss = torch.mean((y-yhat)**2)
# step3
loss.backward()
# step4
net.weight.data = net.weight.data - 0.1*net.weight.grad
net.weight.grad = Noneplt.plot(x,y,'o')
plt.plot(x,net(X).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-106-output-1.png)
step4의 다른버전: 옵티마이저!
ver1: net = torch.nn.Linear(1,1,bias=True)
- 준비
net = torch.nn.Linear(1,1)
net.weight.data = torch.tensor([[10.0]])
net.bias.data = torch.tensor([[-5.0]]) optimizr = torch.optim.SGD(net.parameters(),lr=1/10) # step4가 너무 귀찮기 때문에 net파라미터를 받아서 업데이트하고 청소해주는 오브젝트를 하나 만들기
# optim.SGD(parameter, lr(alpha)=0.1)
# net.parameters() = generator 어쩌고 튀어나오는데 이거 넣어주기 - step1~3
yhat = net(x) loss = torch.mean((y-yhat)**2) loss.backward() - step4
(update 전)
net.weight.data, net.bias.data ## 값은 업데이트 전(tensor([[10.]]), tensor([[-5.]]))
net.weight.grad, net.bias.grad ## 미분값은 청소전 (tensor([[11.8893]]), tensor([[-13.4225]]))
(update)
optimizr.step() # update 진행해줌
optimizr.zero_grad() # grad값 청소(update 후)
net.weight.data, net.bias.data ## 값은 업데이트 되었음 (tensor([[8.8111]]), tensor([[-3.6577]]))
net.weight.grad, net.bias.grad ## 미분값은 0으로 초기화하였음 (tensor([[0.]]), tensor([[0.]]))
- 반복
net = torch.nn.Linear(1,1)
net.weight.data = torch.tensor([[10.0]])
net.bias.data = torch.tensor([-5.0])
optimizr = torch.optim.SGD(net.parameters(),lr=1/10) plt.plot(x,y,'o')
plt.plot(x,net(x).data,'--')for epoc in range(30):
# step1
yhat = net(x)
# step2
loss = torch.mean((y-yhat)**2)
# step3
loss.backward()
# step4
optimizr.step(); optimizr.zero_grad() plt.plot(x,y,'o')
plt.plot(x,net(x).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-120-output-1.png)
ver2: net = torch.nn.Linear(2,1,bias=False)
- 바로 반복하겠습니다..
net = torch.nn.Linear(2,1,bias=False)
net.weight.data = torch.tensor([[-5.0, 10.0]])
optimizr = torch.optim.SGD(net.parameters(),lr=1/10) for epoc in range(30):
yhat = net(X) # ver1에서는 스몰x였는데 여기서는 라지X
loss = torch.mean((y-yhat)**2)
loss.backward()
optimizr.step(); optimizr.zero_grad() plt.plot(x,y,'o')
plt.plot(x,net(X).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-123-output-1.png)
Appendix: net.parameters()의 의미? (선택학습)
- iterator, generator의 개념필요 - https://guebin.github.io/IP2022/2022/06/06/(14주차)-6월6일.html, 클래스공부 8단계 참고
- 탐구시작: 네트워크 생성
net = torch.nn.Linear(in_features=1,out_features=1)
net.weightParameter containing:
tensor([[-0.1656]], requires_grad=True)
net.biasParameter containing:
tensor([0.8529], requires_grad=True)
- torch.optim.SGD? 를 확인하면 params에 대한설명에 아래와 같이 되어있음
params (iterable): iterable of parameters to optimize or dicts defining
parameter groups
- 설명을 읽어보면 params에 iterable object를 넣으라고 되어있음 (iterable object는 숨겨진 명령어로 __iter__를 가지고 있는 오브젝트를 의미)
set(dir(net.parameters)) & {'__iter__'}set()
set(dir(net.parameters())) & {'__iter__'}{'__iter__'}
- 무슨의미?
_generator = net.parameters()_generator.__next__()Parameter containing:
tensor([[-0.1656]], requires_grad=True)
_generator.__next__()Parameter containing:
tensor([0.8529], requires_grad=True)
_generator.__next__()StopIteration:
- 이건 이런느낌인데?
_generator2 = iter([net.weight,net.bias])_generator2<list_iterator at 0x7efce86d5dd0>
_generator2.__next__()Parameter containing:
tensor([[-0.1656]], requires_grad=True)
_generator2.__next__()Parameter containing:
tensor([0.8529], requires_grad=True)
_generator2.__next__()StopIteration:
- 즉 아래는 같은코드이다.
### 코드1
_generator = net.parameters()
torch.optim.SGD(_generator,lr=1/10)
### 코드2
_generator = iter([net.weight,net.bias])
torch.optim.SGD(_generator,lr=1/10)
### 코드3 (이렇게 써도 코드2가 실행된다고 이해할 수 있음)
_iterator = [net.weight,net.bias]
torch.optim.SGD(_iterator,lr=1/10) 결론: net.parameters()는 net오브젝트에서 학습할 파라메터를 모두 모아 리스트(iterable object)로 만드는 함수라 이해할 수 있다.
- 응용예제1
What = torch.tensor([[-5.0],[10.0]],requires_grad=True)
optimizr = torch.optim.SGD([What],lr=1/10) plt.plot(x,y,'o')
plt.plot(x,(X@What).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-138-output-1.png)
for epoc in range(30):
yhat = X@What
loss = torch.mean((y-yhat)**2)
loss.backward()
optimizr.step();optimizr.zero_grad() plt.plot(x,y,'o')
plt.plot(x,(X@What).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-140-output-1.png)
- 응용예제2
b = torch.tensor(-5.0,requires_grad=True)
w = torch.tensor(10.0,requires_grad=True)
optimizr = torch.optim.SGD([b,w],lr=1/10)plt.plot(x,y,'o')
plt.plot(x,(w*x+b).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-142-output-1.png)
for epoc in range(30):
yhat = b+ w*x
loss = torch.mean((y-yhat)**2)
loss.backward()
optimizr.step(); optimizr.zero_grad()plt.plot(x,y,'o')
plt.plot(x,(w*x+b).data,'--')_9월 28일__ipynb의_사본_files/figure-html/cell-144-output-1.png)
Logistic regression
motive
- 현실에서 이런 경우가 많음 - \(x\)가 커질수록 (혹은 작아질수록) 성공확률이 증가함.
# EX) x는 학점이고.. y는 취업할 확률- (X,y)는 어떤모양?
_df = pd.DataFrame({'x':range(-6,7),'y':[0,0,0,0,0,0,1,0,1,1,1,1,1]})
_df | x | y | |
|---|---|---|
| 0 | -6 | 0 |
| 1 | -5 | 0 |
| 2 | -4 | 0 |
| 3 | -3 | 0 |
| 4 | -2 | 0 |
| 5 | -1 | 0 |
| 6 | 0 | 1 |
| 7 | 1 | 0 |
| 8 | 2 | 1 |
| 9 | 3 | 1 |
| 10 | 4 | 1 |
| 11 | 5 | 1 |
| 12 | 6 | 1 |
plt.plot(_df.x,_df.y,'o')_9월 28일__ipynb의_사본_files/figure-html/cell-147-output-1.png)
- (예비학습) 시그모이드라는 함수가 있음
xx = torch.linspace(-6,6,100) # -6에서 6까지 100개..
def f(x):
return torch.exp(x)/(1+torch.exp(x)) plt.plot(_df.x,_df.y,'o')
plt.plot(xx,f(xx)) # f(xx) = f(1*xx) 얌.. 근데 만약 f(5*xx)하면 기울기가 더 급해져.. 애매한 부분이 더 적어지고 스펙에 대한 영향을 ... f(2.5*xx)-1.2 (우측으로 1.2 이동) 이렇게 튜닝이 가능_9월 28일__ipynb의_사본_files/figure-html/cell-149-output-1.png)
model
- \(x\)가 커질수록 \(y=1\)이 잘나오는 모형은 아래와 같이 설계할 수 있음 <— 외우세요!!!
$y_i Ber(_i),$ where \(\pi_i = \frac{\exp(w_0+w_1x_i)}{1+\exp(w_0+w_1x_i)}\)
\(\hat{y}_i= \frac{\exp(\hat{w}_0+\hat{w}_1x_i)}{1+\exp(\hat{w}_0+\hat{w}_1x_i)}=\frac{1}{1+\exp(-\hat{w}_0-\hat{w}_1x_i)}\)
\(loss= - \sum_{i=1}^{n} \big(y_i\log(\hat{y}_i)+(1-y_i)\log(1-\hat{y}_i)\big)\) <— 외우세요!!
# 베르누이.. pi i 라는 건.. 왜 p가 아니고 pi냐? 사람마다 합격할 확률이 다르기 때문에.
# x가 무한대로 가면 pi i 는 1에 가까워지고 마이너스 무한대로 가면 0에가까워진다
# loss는 MSE로 하긴 어렵고,, 라이클리우드?????????? 설명이기니까 위에 그냥 외우기
# y i = 0 일대랑 1 일때 저식에 넣어서 그래프 그려서 생각해보기... loss는 yi랑 y값이 비슷하면 loss 값이 작아짐toy example
- 예제시작
x=torch.linspace(-1,1,2000).reshape(2000,1)
w0= -1
w1= 5
u = w0+x*w1
v = torch.exp(u)/(1+torch.exp(u)) # v=πi, 즉 확률을 의미함, v는 성공할확률
y = torch.bernoulli(v)
# torch.bernoulli(toch.tensor([0.5]*100)) 0,1 반복해서 뽑힘. 0.5는 확률!!!!!plt.scatter(x,y,alpha=0.05) # 여기서 알파가 투명도인듯???????????
plt.plot(x,v,'--r')_9월 28일__ipynb의_사본_files/figure-html/cell-152-output-1.png)
- 우리의 목적: \(x\)가 들어가면 빨간선 \(\hat{y}\)의 값을 만들어주는 mapping을 학습해보자.
# 최초의 곡선
# w0hat = -1
# w1hat = 3
# yhat = f(w0hat+x*w1hat)
# plt.plot(x,y, 'o', alpha=0.05)
# plt.plot(x,v,'--')
# plt.plot(x,yhat,'--r')SyntaxError: ignored
# sigmoid함수만들엇던걸...............